//////////////////////////////////////////////////////////////////////////
#pragma once


//////////////////////////////////////////////////////////////////////////
// Setup for a Window's DLL if needed.
#if defined( _WINDOWS ) && defined( BUILDING_FILESYSTEM_DLL )
#	ifdef BUILDING_FILESYSTEM
#		define FILESYSTEM_EXPORT	__declspec( dllexport )
#	else
#		define FILESYSTEM_EXPORT	__declspec( dllimport )
#	endif
#else
#	define FILESYSTEM_EXPORT
#endif


//////////////////////////////////////////////////////////////////////////
// Generally required includes.
#include "Core/Core.hpp"
#include <functional>

enum class OpenMode
{
	kRead	=	0,
	kAppend	=	1,
	kWrite	=	2
};


// TODO: The initial wrapping around physfs is complete but the
// wrap is very 1:1, eventually the File_t should be turned into
// a nice little class to clean things up.
namespace FileSystem
{
	class Initializer
	{
	public:
		Initializer( const char* arg0, const std::string& company, const std::string& game, const std::string& arcExt );
		~Initializer();
	};


	// Just hiding physfs.
	typedef intptr_t			File_t;

	//
	const char					DirSeparator();
	std::string					CurrentDirectory();
	std::string					BaseDirectory();
	std::string					UserDirectory();

	std::string					GameLocalStorage( const std::string& comp, const std::string& game );
	bool						CreateAndActivate( const std::string& comp, const std::string& game );

	std::string					WriteDirectory();
	bool						WriteDirectory( const std::string& );

	bool						Mount( const std::string&, const std::string& where=std::string(), bool prepend=true );
	bool						RemoveSearchPath( const std::string& );

	bool						Exists( const std::string& );
	bool						IsDirectory( const std::string& );
	bool						MakeDirectory( const std::string& );
	bool						Delete( const std::string& );

	int64_t						LastModTime( const std::string& );

	std::string					RealDirectory( const std::string& );

	File_t						Open( const std::string&, OpenMode m=OpenMode::kRead );
	bool						Close( File_t );

	int64_t						Read( File_t, void* buffer, size_t size );
	int64_t						Write( File_t, const void* buffer, size_t size );

	bool						Eof( File_t );
	bool						Seek( File_t, uint64_t );
	int64_t						Length( File_t );

	bool						Flush( File_t );

	typedef std::function< void ( const std::string& ) >	NameCallback_t;
	void						FileList( const std::string& dir, NameCallback_t );
	void						DirList( const std::string& dir, NameCallback_t );
	void						SearchPaths( NameCallback_t );

	std::string					ReadFileAsString( const std::string& fn );
}
